package cn.lichenes.service.impl;

import cn.lichenes.entity.Address;
import cn.lichenes.entity.Indent;
import cn.lichenes.entity.Phone;
import cn.lichenes.entity.User;
import cn.lichenes.repository.AddressRepository;
import cn.lichenes.repository.IndentRepository;
import cn.lichenes.repository.PhoneRepository;
import cn.lichenes.service.IndentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.Date;

@Service
public class IndentServiceImpl implements IndentService{

    @Autowired
    private IndentRepository indentRepository;
    @Autowired
    private AddressRepository addressRepository;
    @Autowired
    private PhoneRepository phoneRepository;

    public boolean add(User user, Integer pid) {
        Indent indent = new Indent();
        Phone phone = new Phone();
        phone.setpId(pid);
        indent.setUser(user);
        indent.setPhone(phone);
        indent.setoTime(new Date());
        indent.setoStatus(0);
        Indent save = indentRepository.save(indent);
        if (save != null){
            return true;
        }
        return false;
    }

    public Page<Indent> findAll(User user, Integer page) {
        PageRequest pageRequest = PageRequest.of(page - 1, 6);
        Specification<Indent> specification = new Specification<Indent>() {
            public Predicate toPredicate(Root<Indent> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                Predicate predicate = criteriaBuilder.and(criteriaBuilder.equal(root.get("user").as(user.getClass()), user), criteriaBuilder.equal(root.get("oStatus"), 0));
                return predicate;
            }
        };
        return indentRepository.findAll(specification, pageRequest);
    }

    public boolean delete(Integer id) {
        indentRepository.deleteById(id);
        return true;
    }

    public Page<Indent> findByUser(User user, Integer page) {
        PageRequest pageRequest = PageRequest.of(page - 1, 4, Sort.by(Sort.Direction.DESC,"oTime"));
        Specification<Indent> specification = new Specification<Indent>() {
            public Predicate toPredicate(Root<Indent> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                Predicate predicate = criteriaBuilder.and(criteriaBuilder.equal(root.get("user").as(user.getClass()), user), criteriaBuilder.gt(root.get("oStatus"), 0));
                return predicate;
            }
        };
        return indentRepository.findAll(specification, pageRequest);
    }

    public boolean sign(Integer id) {
        Indent indent = indentRepository.findById(id).get();
        indent.setoStatus(3);
        indent.setoFinshTime(new Date());
        Indent save = indentRepository.save(indent);
        if (save != null){
            return true;
        }
        return false;
    }

    public Page<Indent> getAll(Integer page) {
        Order order = new Order(Direction.ASC,"oStatus");
        PageRequest pageRequest = PageRequest.of(page - 1, 10, Sort.by(order));
        Specification<Indent> specification = new Specification<Indent>() {
            public Predicate toPredicate(Root<Indent> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                return criteriaBuilder.gt(root.get("oStatus"), 0);
            }
        };
        return indentRepository.findAll(specification,pageRequest);
    }

    public boolean updateIndent(Integer id) {
        Indent indent = indentRepository.findById(id).get();
        indent.setoStatus(2);
        Indent save = indentRepository.save(indent);
        if (save != null){
            return true;
        }
        return false;
    }

    public Indent findById(Integer id) {
        return indentRepository.findById(id).get();
    }

    public boolean addAddress(Integer oid, Integer aid) {
        Indent indent = indentRepository.findById(oid).get();
        Address address = addressRepository.findById(aid).get();
        indent.setAddress(address);
        Indent save = indentRepository.save(indent);
        if (save != null){
            return true;
        }
        return false;
    }

    public boolean alipayIndent(Integer oId) {
        Indent indent = indentRepository.findById(oId).get();
        Phone phone = indent.getPhone();
        phone.setpResidue(phone.getpResidue()-1);
        phone.setpSales(phone.getpSales()+1);
        Phone savePhone = phoneRepository.save(phone);
        indent.setPhone(savePhone);
        indent.setoStatus(1);
        indent.setoFinshTime(new Date());
        Indent save = indentRepository.save(indent);
        if (save != null){
            return true;
        }
        return false;
    }
}
